Parte 3: Herramientas avanzadas de ejecución remota

En la sección anterior entrenamos un modelo juguete usando aprendizaje federado. Lo hicimos con .send() y .get() en nuestro modelo, enviándolo a la ubicación de los datos de entrenamiento, actualizándolo y luego traerlo de vuelta. Sin embargo, al final del ejemplo nos dimos cuenta de que necesitamos ir un poco más lejos para proteger la privacidad de las personas. Necesitamos sacar el promedio de los gradientes antes llamando .get(). De esa manera, no veremos el gradiente exacto de nadie (¡protegiendo mejor la privacidad!)

Pero, para poder hacer esto, necesitamos un poco más:

  • Usa un puntero para enviar un tensor directamente a otro trabajador

Y además, mientras estamos aquí, vamos a aprender otras operaciones avanzadas de tensores que nos ayudarán con este ejemplo y otros en el futuro!

Autores:

Traductores:


In [ ]:
import torch
import syft as sy
hook = sy.TorchHook(torch)

Sección 3.1 - Punteros a punteros

Como sabes, los PointerTensor se sienten como tensores normales. De hecho, son tan parecidos que hasta podemos tener punteros a punteros. ¡Míralo!


In [ ]:
bob = sy.VirtualWorker(hook, id='bob')
alice = sy.VirtualWorker(hook, id='alice')

In [ ]:
# esto es un tensor local
x = torch.tensor([1,2,3,4])
x

In [ ]:
# esto envía el tensor local a Bob
x_ptr = x.send(bob)

# ahora esto es un puntero
x_ptr

In [ ]:
# ahora podemos ENVIAR EL PUNTERO a ¡alice!
pointer_to_x_ptr = x_ptr.send(alice)

pointer_to_x_ptr

¿Qué ha pasado?

Entonces, en el ejemplo pasado, creamos un tensor llamado 'x' y lo enviamos a Bob, creando un puntero en nuestra máquina local (x_ptr).

Luego, llamamos x_ptr.send(alice) el cual envió el puntero a Alice.

Nota, ¡Esto no movió los datos! en vez, ¡movió el puntero a los datos!


In [ ]:
# Como puedes ver arriba, Bob todavía tiene los datos (los datos siempre están guardados en un tipo LocalTensor)
bob._objects

In [ ]:
# Alice, por otro lado, tiene x_ptr!! (mira como apunta a Bob)
alice._objects

In [ ]:
# y también podemos usar .get() para obtener x_ptr de vuelta
x_ptr = pointer_to_x_ptr.get()
x_ptr

In [ ]:
# y luego podemos usar x_ptr para obtener x de ¡Bob!
x = x_ptr.get()
x

Aritmética en Puntero -> Puntero -> Objeto de datos

Justo como punteros normales, podemos hacer operaciones arbitrarias en estos tensores


In [ ]:
bob._objects

In [ ]:
alice._objects

In [ ]:
p2p2x = torch.tensor([1,2,3,4,5]).send(bob).send(alice)

y = p2p2x + p2p2x

In [ ]:
bob._objects

In [ ]:
alice._objects

In [ ]:
y.get().get()

In [ ]:
bob._objects

In [ ]:
alice._objects

In [ ]:
p2p2x.get().get()

In [ ]:
bob._objects

In [ ]:
alice._objects

Sección 3.2 - Operaciones en cadena de punteros

En la sección anterior cuando llamamos una operación .send() o un .get(), se llamó dicha operación directamente en un tensor de nuestra máquina. Sin embargo, si tienes una cadena de punteros, algunas veces tienes que llamar operaciones como .get() o .send() en el último puntero de la cadena de punteros (como enviar datos directamente de un trabajador a otro). Para realizar esto, debes usar funciones que están especialmente diseñadas para esta operación que preserva privacidad.

Estas funciones están de la forma:

  • my_pointer2pointer.move(another_worker)

In [ ]:
# x es ahora un puntero a puntero a dato que vive en la máquina de Bob
x = torch.tensor([1,2,3,4,5]).send(bob)

In [ ]:
print('  bob:', bob._objects)
print('alice:',alice._objects)

In [ ]:
x = x.move(alice)

In [ ]:
print('  bob:', bob._objects)
print('alice:',alice._objects)

In [ ]:
x

¡Excelente! Ahora estamos equipados con las herramientas para realizar promedio de gradiente remoto usando un ¡agregador confiable!

!Felicitaciones! - !Es hora de unirte a la comunidad!

¡Felicitaciones por completar esta parte del tutorial! Si te gustó y quieres unirte al movimiento para preservar la privacidad, propiedad descentralizada de IA y la cadena de suministro de IA (datos), puedes hacerlo de las ¡siguientes formas!

Dale una estrella a PySyft en GitHub

La forma más fácil de ayudar a nuestra comunidad es por darle estrellas a ¡los repositorios de Github! Esto ayuda a crear consciencia de las interesantes herramientas que estamos construyendo.

¡Únete a nuestro Slack!

La mejor manera de mantenerte actualizado con los últimos avances es ¡unirte a la comunidad! Tú lo puedes hacer llenando el formulario en http://slack.openmined.org

¡Únete a un proyecto de código!

La mejor manera de contribuir a nuestra comunidad es convertirte en un ¡contribuidor de código! En cualquier momento puedes ir al Github Issues de PySyft y filtrar por "Proyectos". Esto mostrará todos los tiquetes de nivel superior dando un resumen de los proyectos a los que ¡te puedes unir! Si no te quieres unir a un proyecto, pero quieres hacer un poco de código, también puedes mirar más mini-proyectos "de una persona" buscando por Github Issues con la etiqueta "good first issue".

Donar

Si no tienes tiempo para contribuir a nuestra base de código, pero quieres ofrecer tu ayuda, también puedes aportar a nuestro Open Collective". Todas las donaciones van a nuestro web hosting y otros gastos de nuestra comunidad como ¡hackathons y meetups!

OpenMined's Open Collective Page